<!--
 * @Description  :
 * @Author       : YiDing Xue
 * @Date         : 2023-02-28
 * @LastEditors  : YiDing Xue
 * @LastEditTime : 2023-03-10
-->
<template>
  <AppPage>
    <section m-auto mt-10>
      <nut-image class="m-auto" radius="10" :src="audioStore.playInfo.imgUrl" width="70vw" height="70vw" />
      <div flex justify-center items-center mt-20>
        <h2 class="fw-500 w-50% text-right text-ellipsis--l1">{{ audioStore.playInfo.episodeName }}</h2>
        <TheIcon icon="tabler:minus-vertical" :size="24" />
        <h2 class="fw-500 w-50% text-ellipsis--l1">{{ audioStore.playInfo.author }}</h2>
      </div>
    </section>
    <section class="mt-20">
      <div flex justify-between items-start>
        <span @click="speedPlay(-15)">
          <TheIcon icon="mdi:rewind-15" :size="24" color="#747474" />
        </span>

        <div>
          <n-slider
            v-model:value="audioStore.playInfo.endTime"
            :default-value="audioStore.playInfo.startTime"
            :disabled="!audioStore.playStatus"
            class="w-70vw"
            :max="audioStore.playInfo.seconds"
            :tooltip="false"
            @update:value="updateSlider"
          >
            <template #thumb>
              <div class="bg-[#fde782] w-24 h-24 b-rounded-50" />
            </template>
          </n-slider>
          <div class="color-[var(--color-text)]" m-t-10 text-12 flex justify-between>
            <div>{{ timeFormat(audioStore.playInfo.endTime) }}</div>
            <div>{{ audioStore.playInfo.formatSeconds }}</div>
          </div>
        </div>
        <span @click="speedPlay(15)">
          <TheIcon icon="mdi:fast-forward-15" :size="24" color="#747474" />
        </span>
      </div>

      <div w-85vw m-x-auto mt-30 flex justify-between items-center>
        <TheIcon :size="30" color="#707070" icon="ri:play-list-2-fill" @click="categoryPopupShow" />
        <TheIcon :size="32" :color="audioStore.playInfo.sort === 1 ? '#c6c6c6' : '#707070'" icon="tabler:player-skip-back-filled" @click="audioStore.switchEpisode(true)" />
        <TheIcon v-if="audioStore.playStatus" icon="tabler:player-pause-filled" :size="75" color="#fcd006" @click="ifPlay(false)" />
        <TheIcon v-else icon="material-symbols:play-circle-rounded" :size="75" @click="ifPlay(true)" />
        <TheIcon :size="32" color="#707070" icon="tabler:player-skip-forward-filled" @click="audioStore.switchEpisode(false)" />
        <div @click="speedPopupShow">
          <nut-image relative :src="speedImg" width="32" />
          <div class="c-[#777] absolute top--6 left-20 text-12">×{{ speedValue[0] }}</div>
        </div>
      </div>

      <div w-60vw m-x-auto mt-30 flex justify-between items-center>
        <TheIcon :size="30" color="#707070" icon="mdi:alpha-e-circle-outline" />
        <TheIcon :size="30" color="#707070" icon="mdi:book-open-page-variant-outline" />
        <TheIcon :size="30" color="#707070" icon="material-symbols:library-books-rounded" />
      </div>
    </section>

    <nut-popup v-model:visible="speedPopup" round position="bottom">
      <nut-picker v-model="speedValue" :columns="columns" @confirm="popupConfirm" @cancel="speedPopup = false" />
    </nut-popup>

    <nut-popup v-model:visible="categoryPopup" round position="bottom">
      <section h-55vh>
        <nut-infinite-loading v-model="infinityValue" :has-more="hasMore" @load-more="loadMore">
          <nut-pull-refresh v-model="refresh" @refresh="refreshFun">
            <article v-for="(item, index) in catalogueList" :key="index" flex justify-between items-center mt-5 bg-white px-10 py-5>
              <p :class="audioStore.playInfo.sort === item.sort ? 'color-[#fcd006]' : ''" @click="play(item, true)">{{ item.episodeName }}</p>
              <div>
                <nut-animate v-if="audioStore.playStatus || audioStore.playInfo.sort === item.sort" type="ripple" :loop="true">
                  <TheIcon icon="material-symbols:bar-chart" :size="24" color="#fcd006" @click="play(item, false)" />
                </nut-animate>
                <TheIcon v-else icon="material-symbols:play-circle-rounded" :size="24" @click="play(item, true)" />
              </div>
            </article>
          </nut-pull-refresh>
        </nut-infinite-loading>
      </section>
    </nut-popup>
  </AppPage>
</template>

<script setup>
import { useAudioStore } from '@/store'
import { timeFormat, _debounce } from '~/src/utils'
import { audioSource, catalogue } from '~/src/api/works'
import speedImg from '@/assets/images/speed.png'
import { isEmpty } from '~/src/utils/common'

const audioStore = useAudioStore()
const route = useRoute()
const categoryPopup = ref(false)
const speedPopup = ref(false) // 倍速弹出层
const speedValue = ref(['1']) // 倍速默认值
const columns = ref([
  { text: '0.5倍速', value: '0.5' },
  { text: '1倍速', value: '1' },
  { text: '1.5倍速', value: '1.5' },
  { text: '2倍速', value: '2' }
])
const catalogueList = ref([])
const refresh = ref(false) // 刷新
const infinityValue = ref(false) // 触发加载中
const hasMore = ref(true) // 加载更多
let params = { page: 1, limit: 10, albumId: null, type: 1 } // 分页参数

onMounted(() => {
  if (isEmpty(route.query.albumId)) {
    return
  }
  getAudioSource()
})

/** 获取播放资源 */
const getAudioSource = async () => {
  const { data: result } = await audioSource(route.query.albumId, route.query.sort)
  if (!result) {
    return $message.error('资源获取失败,请联系客服')
  }
  audioStore.setPlayInfo(result)
  audioStore.setPlayStatus(true)
  countPage(audioStore.playInfo.sort)
  params.moduleWorksId = route.query.moduleWorksId
}

/** 计算传过来的集数是第几页 */
const countPage = sort => {
  // 计算当前播放剧集是第几页
  params.page = sort % params.limit === 0 ? parseInt(sort / params.limit) : parseInt(sort / params.limit) + 1
}

/** 下拉刷新 */
const refreshFun = () => {
  countPage(catalogueList.value[0].sort)
  if (params.page === 1) {
    setTimeout(() => {
      refresh.value = false
    }, 800)
    return
  }
  params.page--
  getCategory(false)
  setTimeout(() => {
    refresh.value = false
  }, 800)
}

/** 触底加载 */
const loadMore = () => {
  countPage(catalogueList.value.at(-1).sort)
  if (hasMore.value) {
    params.page++
  }
  getCategory(true)
  setTimeout(() => {
    infinityValue.value = false
  }, 800)
}

/** 点击音频播放 */
const play = async (playInfo, playStatus) => {
  // 判断是否需要付费
  if (playInfo.lock) {
    $message.warning('请进入【我的】页面添加一对一专属客服')
    return
  }
  const { data: result } = await audioSource(route.query.albumId, playInfo.sort)
  if (result) {
    audioStore.setPlayInfo(result)
    audioStore.setPlayStatus(playStatus)
    categoryPopup.value = false
  }
}

/** 目录弹出层 */
const categoryPopupShow = () => {
  categoryPopup.value = true
  getCategory(true)
}

/**
 * 获取目录
 * @param {Boolean} isDown 触底 true / 触顶 false
 *
 */
const getCategory = _debounce(async isDown => {
  const { data: result } = await catalogue(params)
  if (result.list.length) {
    catalogueList.value = isDown ? [...catalogueList.value, ...result.list] : [...result.list, ...catalogueList.value]
    return
  }
  hasMore.value = false
}, 500)

/** 快进/后退 */
const speedPlay = time => {
  if (audioStore.playStatus) {
    // 时长
    let duration = audioStore.playInfo.seconds
    // 快进/后退时间
    let seekTime = time + audioStore.playInfo.endTime

    if (seekTime < 0) {
      seekTime = 0
    }

    if (seekTime > duration) {
      seekTime = duration
    }
    audioStore.setPlayTime(seekTime)
    audioStore.audioRef.currentTime = seekTime
    return
  }

  $message.warning('请在播放状态下操作')
}

/** 倍速弹出层显示 */
const speedPopupShow = () => {
  if (!audioStore.playStatus) {
    return $message.warning('请在播放状态下操作')
  }
  speedPopup.value = true
}

/** 倍速确认 */
const popupConfirm = ({ selectedValue }) => {
  audioStore.setPlaybackRate(selectedValue[0])
  speedPopup.value = false
}

/** 播放按钮 */
const ifPlay = status => {
  audioStore.setPlayStatus(status)
}

/** 进度条改变 */
const updateSlider = value => {
  audioStore.setPlayTime(value)
  audioStore.audioRef.currentTime = value
}
</script>
<style>
.n-slider-rail__fill {
  background-color: #fde782 !important;
  position: relative;
  position: absolute;
}
</style>
